﻿using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sharp.Interprocess.MemoryManager
{
    [ProtoContract(SkipConstructor = true)]
    public class SegmentBlock : IEquatable<SegmentBlock>
    {
        [ProtoMember(1,DataFormat = DataFormat.FixedSize)]
        public int BlockSize { get; set; }

        [ProtoMember(2, DataFormat = DataFormat.FixedSize)]
        public long BlockOffset { get; set; }

        public long BuddyBlockOffset
        {
            get
            {
                //flip size's power of 2-th bit of the offset
                return BlockOffset ^ (1 << MemoryManagerUtil.PowerOf2ByResult[BlockSize]);
            }
        }

        #region Constructor(s)

        public SegmentBlock(int blockSize, long blockOffset)
        {
            BlockSize = blockSize;
            BlockOffset = blockOffset;
        }

        #endregion

        #region Utility Methods / Overrides

        public override bool Equals(object obj)
        {
            var otherSegmentBlock = obj as SegmentBlock;
            if (otherSegmentBlock == null) return false;
            else return BlockOffset == otherSegmentBlock.BlockOffset && BlockSize == otherSegmentBlock.BlockSize;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hashCode = 17;
                hashCode = hashCode * 23 + BlockOffset.GetHashCode();
                hashCode = hashCode * 23 + BlockSize.GetHashCode();
                return hashCode;
            }
        }

        public bool Equals(SegmentBlock other)
        {
            return BlockOffset == other.BlockOffset && BlockSize == other.BlockSize;
        }

        #endregion
    }
}
